package com.redside.webapp.validator;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.oro.text.perl.Perl5Util;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;

import com.redside.view.BusinessAssociatorView;

/**
 * Validator for BusinessAssociatorView
 */

public class BusinessAssociatorValidator implements Validator {

    private final Log logger = LogFactory.getLog(BusinessAssociatorValidator.class);
    private static final int MINIMUM_ZIPCODE_LENGTH = 5;
    private static final String PHONE_REGEXP = "/(\\({0,1})(\\d{3})(\\){0,1})(\\s|-)*(\\d{3})(\\s|-)*(\\d{4})/";
    private static final String EMAIL_REGEXP = "/^[^@]+@[^@.]+\\.[^@]*\\w\\w$/";

    @SuppressWarnings("unchecked")
    public boolean supports(Class clazz) {
        return clazz.equals(BusinessAssociatorView.class);
    }

    public void validateBusinessChecked(Object obj, Errors errors) {
        BusinessAssociatorView associatorView = (BusinessAssociatorView) obj;
        if (null == associatorView) {
            errors.rejectValue("BusinessAssociatorView is null!", null, null,
                    "BusinessAssociatorView is null!");
        } else {
            if (associatorView.getBusinessId() == null && associatorView.isExistingBusiness()) {
                errors.reject("existingbusiness",
                    "When selecting 'Use Checked Business' button, you need to select a business from the list.");
            }
        }

    }
    public void validateBusinessFields(Object obj, Errors errors) {
        BusinessAssociatorView associatorView = (BusinessAssociatorView) obj;
        if (null == associatorView) {
            errors.rejectValue("BusinessAssociatorView is null!", null, null,
                    "BusinessAssociatorView is null!");
        } else {
            logger.debug("validateBusinessFields...");
            logger.debug("associatorView.getBusinessCategoryId()..."+associatorView.getBusinessCategoryId());
            
            ValidationUtils.rejectIfEmpty(errors, "business.businessName",
                    "errors.required", new Object[] { "Business Name" },
                    "Business Name is required.");
            
            if (associatorView.getBusinessCategoryId() == 0) {
                logger.debug("********************getBusinessCategoryId...");
                errors.rejectValue("businessCategoryId", "errors.required", new Object[] { "Type of Business" },
                        "Type of Business is required.");
            }
            
            ValidationUtils.rejectIfEmpty(errors, "business.businessAddress1",
                    "errors.required", new Object[] { "Address" },
                    "Business Address is required.");
            
            ValidationUtils.rejectIfEmpty(errors, "business.businessCity",
                    "errors.required", new Object[] { "City" }, "City is required.");
            
            ValidationUtils.rejectIfEmpty(errors, "business.businessZip",
                    "errors.required", new Object[] { "Zip Code" }, "Zip Code is required."); 
            
            if (!(associatorView.getBusiness().getAddress().getPostalCode().trim().equals("")) 
                    && associatorView.getBusiness().getAddress().getPostalCode().trim().length() < MINIMUM_ZIPCODE_LENGTH) {
                errors.rejectValue("business.businessZip", "errors.minlength", new Object[] { "Zip Code",
                        Integer.valueOf(MINIMUM_ZIPCODE_LENGTH) },
                        "The zip code must be at least " + MINIMUM_ZIPCODE_LENGTH
                                + " characters in length.");
            }
            
            if (associatorView.getBusiness().getAddress().getPostalCode() != null 
                    && !(associatorView.getBusiness().getAddress().getPostalCode().trim().equals(""))){
                try{
                    Long.parseLong(associatorView.getBusiness().getAddress().getPostalCode());
                }catch(NumberFormatException e){
                    errors.rejectValue("business.businessZip", "errors.zip", new Object[]{associatorView.getBusiness().getAddress().getPostalCode()}, 
                            associatorView.getBusiness().getAddress().getPostalCode()+" is an invalid Zip Code.");
                }
            }
            
            if (associatorView.getCountyId().equals("")) {
                errors.rejectValue("countyId", "errors.required", new Object[] { "County" },
                "County is required.");
            }
            
            ValidationUtils.rejectIfEmpty(errors, "business.businessPhone",
                    "errors.required", new Object[] { "Phone Number" }, "Phone Number is required.");
            
            Perl5Util perl5Util = new Perl5Util();
            if(associatorView.getBusiness().getBusinessPhone() != null 
                    && !(associatorView.getBusiness().getBusinessPhone().trim().equals(""))){
                if(!perl5Util.match(PHONE_REGEXP, associatorView.getBusiness().getBusinessPhone())) {
                errors.rejectValue("business.businessPhone", "errors.phone", new Object[]{associatorView.getBusiness().getBusinessPhone()},"Phone number is invalid");
                }
            }
            
            if(!(associatorView.getBusiness().getContactEmail().trim().equals(""))){
                if(!perl5Util.match(EMAIL_REGEXP, associatorView.getBusiness().getContactEmail().trim())) {
                    logger.debug("The email: '"+associatorView.getBusiness().getContactEmail()+"' did not pass.");
                    errors.rejectValue("business.contactEmail", "errors.email", new Object[]{associatorView.getBusiness().getContactEmail()},"Email is invalid");
                }
            }
        }
    }
    public void validateActionableStatus(Object obj, Errors errors) {
        BusinessAssociatorView associatorView = (BusinessAssociatorView) obj;
        if (null == associatorView) {
            errors.rejectValue("BusinessAssociatorView is null!", null, null,
                    "BusinessAssociatorView is null!");
        } else {
            if (associatorView.getNatureOfComplaintId().equals("0")
                    || associatorView.getNatureOfComplaintId() == 0) {
                errors.reject("errors.required", new Object[] { "Nature of Complaint" },
                        "Nature of Complaint is required.");
            }
            logger.debug("ABOUT TO VALIDATE NON ACTIONABLE....");
            logger.debug("actionable: "+associatorView.isActionable()+", non-action id: "+associatorView.getNonActionableId());
            if (!associatorView.isActionable()
                    && associatorView.getNonActionableId()==0) {
                errors.reject("errors.actionable.required",
                        "If a complaint is non-actionable, a reason is required.");
            }
            if (associatorView.isActionable()
                    && associatorView.getNonActionableId() > 0) {
                errors.reject("errors.actionable.reason",
                        "If actionable is checked, a non-actionable reason cannot be selected.");
            }
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.springframework.validation.Validator#validate(java.lang.Object,
     *      org.springframework.validation.Errors) Note that the standard
     *      validate method is not called for this wizard because we are not
     *      validating the whole page at once, only pieces at a time.
     */
    public void validate(Object arg0, Errors arg1) {

    }

}
